package menu;

import java.util.ResourceBundle;

import player.Player;
import adapter.Adapter;
import field.Brewery;
import field.Field;
import field.Ownable;
import field.Property;
import field.Shipping;

public class MenuController {

	private int[][] buttons;
	private Adapter adapter;
	private ResourceBundle msg;
	private int [] buyHouse;

	public MenuController(){
		adapter = new Adapter();
		msg = adapter.getBundle();
	}

	public int[] menu(Player p, Field[] fields, Player[] players){
		int[] sellHouse, pawn, unPawn, sellGround; // Liste over grunde. [0] = skal knap vises eller ej
		int[] data = new int[]{0,0,0,0,0,0,0,0};  // Plads [0] = køb hus, [1] = sælg hus, [2] = pantsæt, [3] = hæv pantsætning, [4] = Skal menuen genstartes (1 = ja)
		buyHouse = checkBuyHouse(p, fields);
		sellHouse = checkSellHouse(p, fields);
		pawn = checkPawn(p, fields);
		unPawn = checkUnPawn(p, fields);
		sellGround = checkSellGround(p, fields, players);

		// Antallet af Ownable felter findes
		int l = 0;
		for (int i = 0; i<fields.length; i++){
			if (fields[i] instanceof Ownable){
				l++;
			}
		}
		buttons = new int[6][l+1]; // +1 fordi vi har knap ja/nej på plads [x][0]

		// Data fra menucheck smides i nyt todimensionelt array
		buttons[0][0] = buyHouse[0];
		for (int n=1; n < buyHouse.length; n++){
			buttons[0][n] = buyHouse[n];			
		}
		buttons[1][0] = sellHouse[0];
		for (int n=1; n < sellHouse.length; n++){
			buttons[1][n] = sellHouse[n];			
		}
		buttons[2][0] = pawn[0];
		for (int n=1; n < pawn.length; n++){
			buttons[2][n] = pawn[n];			
		}
		buttons[3][0] = unPawn[0];
		for (int n=1; n < unPawn.length; n++){
			buttons[3][n] = unPawn[n];			
		}
		buttons[4][0] = 1;
		buttons[5][0] = sellGround[0];
		for (int n=1; n < sellGround.length; n++){
			buttons[5][n] = sellGround[n];			
		}

		// Tilføj knap "Fortryd"
		switch (adapter.menu(createButtons(buttons, fields), p.getName())){
		case 0:{
			// Køb hus
			String[] fieldList = new String[buyHouse.length];
			fieldList[0] = msg.getString("Cancel");
			for(int i = 1; i < fieldList.length;i++){
				fieldList[i] = fields[buyHouse[i]].getTitle();
			}
			String choice = adapter.menuDropDown(fieldList, p.getName());

			if (choice == msg.getString("Cancel")){
				System.out.println("Du har valgt Fortryd. Menuen genstartes"); // TESTKODE SKAL FJERNES
				data[4] = 1; // Menuen genstartes når man har valgt fortryd.
			}
			else {
				for (int i=0; i<fields.length;i++){
					if (choice == fields[i].getTitle()){
						data[0] = i;
					}
				}
			}
		}
		break;
		case 1:{
			// Sælg hus
			String[] fieldList = new String[sellHouse.length];
			fieldList[0] = msg.getString("Cancel");
			for(int i = 1; i < fieldList.length;i++){
				fieldList[i] = fields[sellHouse[i]].getTitle();
			}
			String choice = adapter.menuDropDown(fieldList, p.getName());

			if (choice == msg.getString("Cancel")){
				data[4] = 1; 
			}
			else {
				for (int i=0; i<fields.length;i++){
					if (choice == fields[i].getTitle()){
						data[1] = i;
					}
				}
			}
		}
		break;
		case 2:{
			// Pantsæt grund
			String[] fieldList = new String[pawn.length];
			fieldList[0] = msg.getString("Cancel");
			for(int i = 1; i < fieldList.length;i++){
				fieldList[i] = fields[pawn[i]].getTitle();
			}
			String choice = adapter.menuDropDown(fieldList, p.getName());
			if (choice == msg.getString("Cancel")){
				data[4] = 1; 
			}
			else {
				for (int i=0; i<fields.length;i++){
					if (choice == fields[i].getTitle()){
						data[2] = i;
					}
				}
			}
		}
		break;
		case 3:{
			// Hæv pantsætning
			String[] fieldList = new String[unPawn.length];
			fieldList[0] = msg.getString("Cancel");
			for(int i = 1; i < fieldList.length;i++){
				fieldList[i] = fields[unPawn[i]].getTitle();
			}
			String choice = adapter.menuDropDown(fieldList, p.getName());
			if (choice == msg.getString("Cancel")){
				data[4] = 1; 
			}
			else {
				for (int i=0; i<fields.length;i++){
					if (choice == fields[i].getTitle()){
						data[3] = i;
					}
				}
			}
		}
		break;
		case 4:{ // Giv turen videre knap
			for (int i=0;i<data.length;i++){
				data[i] = 0;
			}
		}
		break;
		case 5:{
			// Sælg grund
			String[] fieldList = new String[sellGround.length];
			fieldList[0] = msg.getString("Cancel");
			for(int i = 1; i < fieldList.length;i++){
				fieldList[i] = fields[sellGround[i]].getTitle();
			}
			String choice = adapter.menuDropDown(fieldList, p.getName());
			if (choice == msg.getString("Cancel")){
				data[4] = 1; 
			}
			else {
				for (int i=0; i<fields.length;i++){
					if (choice == fields[i].getTitle()){
						int price = adapter.getInt(fields[i].getTitle(), p.getName());
						String[] pArray = checkPlayers(p, players, price);
						String pChoice = adapter.menuDropDown(pArray, p.getName());
						if (pChoice == msg.getString("Cancel")){
							data[4] = 1; 
						}
						else {
							adapter.showMessage(msg.getString("Sold_House1") + fields[i].getTitle() + " " + msg.getString("Sold_House2")+ pChoice + " " + msg.getString("Sold_House3") + " " + Integer.toString(price));
							for (int j=0;j<players.length;j++){
								if (players[j].getName() == pChoice){
									data[4] = 1;
									data[5] = j; // Købers nummer i arrayet
									data[6] = i; // Feltnummeret
									data[7] = price; // Prisen på feltet
								}
							}
						}
					}
				}
			}
		}
		break;
		}
		
		return data;
	}

	private String[] checkPlayers(Player p, Player[] players, int price) {
		String[] tempOut = new String[5];
		int m=0; // Antal spillere der kan betale prisen for feltet
		
		for (int i=0;i<players.length;i++){
			if (p != players[i] && players[i].getAccount().getBalance() >= price){
				tempOut[m] = players[i].getName();
				m++;
			}
		}
		
		String[] output = new String[m+1]; 
		if (m>0){
			output[0] = msg.getString("Cancel");
		}
		for (int i=1; i<output.length;i++){
			output[i] = tempOut[i-1];
		}

		return output;
	}

	private int[] checkSellGround(Player p, Field[] fields, Player[] players) {
		int[] tempOut = new int[30];
		int m = 0;
		for (int i=0;i<fields.length;i++){
			if (fields[i] instanceof Ownable){
				if (((Ownable) fields[i]).getPawned() == false){
					if (p == ((Ownable) fields[i]).getOwner()){
						if (fields[i] instanceof Shipping || fields[i] instanceof Brewery){
							tempOut[m] = i;
							m++;
						}
						else if(fields[i] instanceof Property){
							if (((Property) fields[i]).getHouseCount() == 0){
								tempOut[m] = i;
								m++;	
							}
						}
					}
				}
			}
		}
		int[] output = new int[m+1]; 
		if (m>0){
			output[0] = 1;
		}
		else {
			output[0] = 0;
		}
		for (int i=1; i<output.length;i++){
			output[i] = tempOut[i-1];
		}

		return output;
	}

	private String[] createButtons(int[][] buttons, Field[] fields) {
		int b = 0;
		for (int n = 0; n < buttons.length; n++){
			if (buttons[n][0] == 1){
				b++;
			}
		}

		String[] showButtons = new String[b];
		int o = 0;
		if (buttons[0][0] == 1){
			showButtons[o] = msg.getString("Buy_House");
			o++;
		}
		if (buttons [1][0] == 1){
			showButtons[o] = msg.getString("Sell_House");
			o++;
		}
		if (buttons [2][0] == 1){
			showButtons[o] = msg.getString("Pawn_Ground");
			o++;
		}
		if (buttons [3][0] == 1){
			showButtons[o] = msg.getString("Unpawn_Ground");
			o++;
		}
		if (buttons [4][0] == 1){
			showButtons[o] = msg.getString("End_Turn");
			o++;
		}
		if (buttons [5][0] == 1){
			showButtons[o] = msg.getString("Sell_Ground");
			o++;
		}
		return showButtons;		
	}



	private int[] checkUnPawn(Player p, Field[] fields) {
		int[] tempOut = new int[30];
		int m = 0;
		for (int i=0;i<fields.length;i++){
			if (fields[i] instanceof Ownable){
				if (((Ownable) fields[i]).getPawned() == true && p == ((Ownable) fields[i]).getOwner() && ((Ownable) fields[i]).getPawnPrice()*1.1 < p.getAccount().getBalance()){
					tempOut[m] = i;
					m++;	
				}
			}
		}

		int[] output = new int[m+1]; 
		if (m>0){
			output[0] = 1;
		}
		else {
			output[0] = 0;
		}
		for (int i=1; i<output.length;i++){
			output[i] = tempOut[i-1];
		}

		return output;
	}

	private int[] checkPawn(Player p, Field[] fields) {
		int[] tempOut = new int[30];
		int m = 0;
		for (int i=0;i<fields.length;i++){
			if (fields[i] instanceof Ownable){
				if (((Ownable) fields[i]).getPawned() == false){
					if (p == ((Ownable) fields[i]).getOwner()){
						if (fields[i] instanceof Shipping || fields[i] instanceof Brewery){
							tempOut[m] = i;
							m++;
						}
						else if(fields[i] instanceof Property){
							if (((Property) fields[i]).getHouseCount() == 0){
								tempOut[m] = i;
								m++;	
							}
						}
					}
				}
			}
		}
		int[] output = new int[m+1]; 
		if (m>0){
			output[0] = 1;
		}
		else {
			output[0] = 0;
		}
		for (int i=1; i<output.length;i++){
			output[i] = tempOut[i-1];
		}

		return output;
	}

	private int[] checkSellHouse(Player p, Field[] fields) {
		int[] bloks = new int[9];
		int[][] grounds = new int[30][2];
		int[] tempOut = new int[30];
		int[] maxBloks = new int[]{4, 2, 3, 3, 3, 3, 3, 3, 2}; // Antal grunde der hører til en blok for Property-felterne.

		int q=0;
		for (int i=0; i<fields.length;i++){
			if (fields[i] instanceof Property){
				if (((Property) fields[i]).getOwner() == p){
					int k = ((Property) fields[i]).getBlock();
					bloks[k]++;
					grounds[q][0] = i;
					grounds[q][1] = k;
					q++;
				}
			}
		}
		int m=0;
		for (int i=0; i<bloks.length;i++){
			if (bloks[i] == maxBloks[i]){
				for (int o=0; o<grounds.length;o++){
					if (i == grounds[o][1]){							
						if (((Property) fields[grounds[o][0]]).getHouseCount() >= 1){
							if (checkSell(grounds[o][0], fields) == true){ // Antal huse tjek
								tempOut[m] = grounds[o][0];
								m++;

							}
						}
					}
				}
			}
		}

		int[] output = new int[m+1]; 
		if (m>0){
			output[0] = 1; 
		}
		else {
			output[0] = 0; 
		}
		for (int i=1; i<output.length;i++){
			output[i] = tempOut[i-1];
		}
		return output;
	}

	/**
	 * Tjekker hvilke grunde en spiller kan købe et hus på
	 * @param p Spilleren der er skal tjekkes på
	 * @param fields Array af Field
	 * @return Array med grunde der kan købes et hus på (arrayet indeholder numrene på grundene i det oprindelige Field array).
	 */
	private int[] checkBuyHouse(Player p, Field[] fields) {
		int[] bloks = new int[9];
		int[][] grounds = new int[30][2];
		int[] tempOut = new int[30];
		int[] maxBloks = new int[]{4, 2, 3, 3, 3, 3, 3, 3, 2}; // Antal grunde der hører til en blok for Property og shipping-felterne.
		int q=0;
		for (int i=0; i<fields.length;i++){
			if (fields[i] instanceof Property){
				if (((Property) fields[i]).getOwner() == p){ //Hvis ejer af felt = spiller
					int k = ((Property) fields[i]).getBlock();
					bloks[k]++; //Tæller op, hvor mange grunde spiller ejer i hver farve/blok. 
					grounds[q][0] = i; //Nummer på det felt der undersøges 
					grounds[q][1] = k; //Farven på feltet/bloknummer 
					q++; //Tæller én array-række, svarende til nyt felt. 
				}
			}
		}
		int m=0;
		for (int i=0; i<bloks.length;i++){ //Kigger bloks[] igennem
			if (bloks[i] == maxBloks[i]){ //Hvis plads i er identisk med plads i i maxblocks, ved vi at spiller ejer alle grunde i block. 
				for (int o=0; o<grounds.length;o++){ //Kigger grounds[] igennem 
					if (i == grounds[o][1]){ //Finder grunde med blocknummer i i groundsarrayet  					
						if (((Property) fields[grounds[o][0]]).getHouseCount() < 5 && ((Property) fields[grounds[o][0]]).getPawned() == false){ //Undersøger om grund har under 5 huse og om grund er pantsat
							if (checkBlock(grounds[o][0], fields) == true){ // Udregner om huse på grunde er fordelt jævnt - hvis true = man må bygge 
								if(p.getAccount().getBalance() >= ((Property) fields[grounds[o][0]]).getBuyBuildingPrice()) { // Penge nok tjek
									tempOut[m] = grounds[o][0]; //Tager aktuelt feltnummer og lægger i midlertidigt array
									m++;
								}	
							}
						}
					}
				}
			}
		}

		int[] output = new int[m+1]; 
		if (m>0){
			output[0] = 1; // Hvis der er grunde spilleren må købe markeres dette.
		}
		else {
			output[0] = 0; // Hvis der ikke er nogen grunde spilleren må købe markeres dette.
		}
		for (int i=1; i<output.length;i++){
			output[i] = tempOut[i-1];
		}
		return output;
	}

	/**
	 * Tjekker for reglen om at der maksimalt må være et hus mere på en grund end på de andre grunde i samme farvekatagori.
	 * @param o Feltnummeret der skal tjekkes
	 * @param fields Array af fields
	 * @return True = Der må bygges, False = Der må ikke bygges på grunden
	 */
	private boolean checkBlock(int o, Field[] fields) {
		int totalHouse = 0;
		int blockHouses = 0;
		for (int h=0; h<fields.length;h++){
			if (fields[h] instanceof Property) {
				if (((Property) fields[o]).getBlock() == ((Property) fields[h]).getBlock()){
					totalHouse = totalHouse + ((Property) fields[h]).getHouseCount();
					blockHouses++;
				}
			}
		}
		int avg = ((int) (totalHouse / blockHouses)) +1;
		if (avg > ((Property) fields[o]).getHouseCount()){
			return true;
		}
		else {
			return false;
		}
	}

	private boolean checkSell(int o, Field[] fields) {
		int totalHouse = 0;
		int blockHouses = 0;
		for (int h=0; h<fields.length;h++){
			if (fields[h] instanceof Property) {
				if (((Property) fields[o]).getBlock() == ((Property) fields[h]).getBlock()){
					totalHouse = totalHouse + ((Property) fields[h]).getHouseCount();
					blockHouses++;
				}
			}
		}
		int avg = ((int) (totalHouse / blockHouses))+1;
		int check = totalHouse % blockHouses;
		if (check !=0 || avg == 1){
			if (avg <= ((Property) fields[o]).getHouseCount()){
				return true;
			}
			else {
				return false;
			}
		}
		else {
			return true;
		}
	}

	public int[] getBuyHouse(){
		return buyHouse;
	}


}
